/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-10     Administrator       the first version
 */
/**
     __  _______  _    ____  _  __      __  __    ____   ___  _____ _____
     \ \/ /_   _|/ \  |  _ \| |/ / 塔   \ \/ /   / ___| / _ \|  ___|_   _| 软
      \  /  | | / _ \ | |_) | ' /  克    \  /____\___ \| | | | |_    | |   件
      /  \  | |/ ___ \|  _ <| . \  创    /  \_____|__) | |_| |  _|   | |   生
     /_/\_\ |_/_/   \_\_| \_\_|\_\ 新   /_/\_\   |____/ \___/|_|     |_|   态

  ******************************************************************************
  *
  * 版权所有： XTARK@塔克创新  版权所有，盗版必究
  * 官网网站： www.xtark.cn
  * 淘宝店铺： https://shop246676508.taobao.com
  * 塔克媒体： www.cnblogs.com/xtark（博客）
    * 塔克微信： 微信公众号：塔克创新（获取最新资讯）
  *
  ******************************************************************************
  * @作  者  Musk Han@XTARK
  * @版  本  V1.0
  * @日  期  2019-8-8
  * @内  容  PS2手柄驱动
  *
  ******************************************************************************
  * @说  明
  *
  *   PS2数据定义
  *   BYTE   DATA   解释
  *   01     idle
  *   02     0x73   手柄的工作模式
  *   03     0x5A   Bit0  Bit1  Bit2  Bit3  Bit4  Bit5  Bit6  Bit7
  *   04     data   SLCT  JOYR  JOYL  STRT   UP   RGIHT  DOWN   L
  *   05     data   L2     R2     L1    R1   /\     O     X    口
  *   06     data   右边摇杆  0x00 = 左    0xff = 右
  *   07     data   右边摇杆  0x00 = 上    0xff = 下
  *   08     data   左边摇杆  0x00 = 左    0xff = 右
  *   09     data   左边摇杆  0x00 = 上    0xff = 下
  *
  ******************************************************************************
  */
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "ps2.h"

#define THREAD_PRIORITY         15
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        10
#define CMD GET_PIN(C,2)
#define DAT GET_PIN(C,3)
#define CLK GET_PIN(B,10)
#define CS GET_PIN(B,12)

////PS手柄的输入输出口
//#define DATA_read()  rt_pin_read(35)
//#define CM_H()       rt_pin_write(34, PIN_HIGH)
//#define CM_L()       rt_pin_write(34, PIN_LOW)
//#define ATT_H()      rt_pin_write(28, PIN_HIGH)
//#define ATT_L()      rt_pin_write(28, PIN_LOW)
//#define CLK_H()      rt_pin_write(26, PIN_HIGH)
//#define CLK_L()      rt_pin_write(26, PIN_LOW)

//PS手柄的输入输出口
//#define DATA_read()  rt_pin_read(DAT)
#define CM_H()        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET)
#define CM_L()        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET)
#define ATT_H()       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define ATT_L()       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define CLK_H()       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET)
#define CLK_L()       HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET)

 JOYSTICK_TypeDef my_joystick;
static rt_thread_t tid1 = RT_NULL;
const rt_uint8_t PS2_cmnd[9] = {0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //请求获取数据命令
static rt_uint8_t PS2_data[9] = {0};//接收的数据

/**
  * @简  述  PS2初始化
  * @参  数  无
  * @返回值  无
  */
void AX_PS2_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    //    rt_pin_mode(CMD, PIN_MODE_OUTPUT);
    //    rt_pin_mode(CLK, PIN_MODE_OUTPUT);
    //    rt_pin_mode(CS,  PIN_MODE_OUTPUT);
    //    rt_pin_mode(DAT, PIN_MODE_INPUT);

    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}



static uint8_t PS2_ReadWriteData(uint8_t data)
{
    uint8_t ref,res;

    for(ref = 0x01; ref > 0x00; ref <<= 1)
    {
        CLK_L();
        if(ref&data)
            CM_H();
        else
            CM_L();
        rt_hw_us_delay(16);
        CLK_H();
       // if(DATA_read())
        if( HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3)==GPIO_PIN_SET)
            res |= ref;
        rt_hw_us_delay(16);
    }
    CM_H();
    return res;
}

void AX_PS2_ScanKey(JOYSTICK_TypeDef *JoystickStruct)
{
    uint8_t i;

    ATT_L();
    rt_hw_us_delay(1);
    for(i=0; i<9; i++)
    {
        PS2_data[i] = PS2_ReadWriteData(PS2_cmnd[i]);
        rt_hw_us_delay(16);
    }

    ATT_H();

    JoystickStruct->mode = PS2_data[1];
    JoystickStruct->btn1 = PS2_data[3];
    JoystickStruct->btn2 = PS2_data[4];
    JoystickStruct->RJoy_LR = PS2_data[5]-1;
    JoystickStruct->RJoy_UD = PS2_data[6];
    JoystickStruct->LJoy_LR = PS2_data[7]-2;
    JoystickStruct->LJoy_UD = PS2_data[8];


}

/******************* (C) 版权 2018 XTARK **************************************/


/* 线程1的入口函数 */
static void thread1_entry(void *parameter)
{

    AX_PS2_Init();
    rt_thread_mdelay(10);
    while (1)
    {
          AX_PS2_ScanKey(&my_joystick);

//          rt_kprintf("MODE:%2x BTN1:%2x BTN2:%2x RJOY_LR:%2x RJOY_UD:%2x LJOY_LR:%2x LJOY_UD:%2x\r\n",
//          my_joystick.mode, my_joystick.btn1, my_joystick.btn2,
//          my_joystick.RJoy_LR, my_joystick.RJoy_UD, my_joystick.LJoy_LR, my_joystick.LJoy_UD);

          rt_thread_mdelay(50);

    }
}


int thread_ps2_init(void)
{
    /* 创建线程1，名称是thread1，入口是thread1_entry*/
    tid1 = rt_thread_create("ps2",
                            thread1_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);

    /* 如果获得线程控制块，启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);

    return 0;
}

INIT_APP_EXPORT(thread_ps2_init);

/******************* (C) 版权 2019 XTARK **************************************/
